package com.example.md.mddemo.filter;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;

/**
 * Copyright © 2018年 ziniuxiaozhu. All rights reserved.
 *
 * @Author 临江仙 hzqiuxm@163.com
 * TODO:亲爱的临江仙，请写点注释吧...........
 * @Date 2018/9/6 14:49
 */

@Order(1)
@WebFilter(filterName = "xssCheckFilter",urlPatterns = "/*")
public class XssCheckFilter implements Filter {

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    // 是否开启SessionCheck过滤器
    @Value("${filter.isEnabled}")
    private  String isEnabled = "0";
    //是否查询头部
    @Value("${filter.isCheckHeader}")
    private  String isCheckHeader = "0";
    //是否检查参数
    @Value("${filter.isCheckParameter}")
    private  String isCheckParameter = "0";
    //是否中断链
    @Value("${filter.isInterruptChain}")
    private  String isInterruptChain = "0";


    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

        logger.info("XssCheckFilter filter execute init.");
        //从配置文件中获取Filter的配置参数
        try {
            // 取是否开启安全过滤器
            if(isEnabled!=null && !"".equals(isEnabled)) {
                this.isEnabled = isEnabled;
            }
            logger.info("isEnabled = {}",isEnabled);

            if(isCheckHeader!=null && !"".equals(isCheckHeader)) {
                this.isCheckHeader = isCheckHeader;
            }
            logger.info("isEnabled = {}",isCheckHeader);


            if(isCheckParameter!=null && !"".equals(isCheckParameter)) {
                this.isCheckParameter = isCheckParameter;
            }
            logger.info("isEnabled = {}",isCheckParameter);

            if(isInterruptChain!=null && !"".equals(isInterruptChain)) {
                this.isInterruptChain = isInterruptChain;
            }
            logger.info("isEnabled = {}",isInterruptChain);
        } catch (RuntimeException e) {
            logger.error("XssCheckFilter filter init error.", e);
        }
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

        if (isEnabled == "0") {
            logger.info("XSS过滤器未启用！ ");
            filterChain.doFilter(servletRequest, servletResponse);
            return;
        }

        // 转型
        HttpServletRequest httpRequest = (HttpServletRequest) servletRequest;
        XssRequestWrapper xssRequest = new XssRequestWrapper(httpRequest);
        logger.info("XssCheckFilter filter execute filter ,url is " + httpRequest.getRequestURL());

        //校验返回真，说明存在xss攻击信息
        boolean isHeaderInvalid = false;
        if (isCheckHeader =="1") {//检查头域，则调用warpper的校验方法
            isHeaderInvalid = xssRequest.validateHeader(httpRequest);
        }

        //校验返回真，说明存在xss攻击信息
        boolean isParameterInvalid = false;
        if (isCheckParameter =="1") {//检查头域，则调用warpper的校验方法
            isParameterInvalid = xssRequest.validateParameter(httpRequest);
        }

        //头域或者参数不合法，则说明有xss攻击威胁，根据配置决定是否返回
        if (isHeaderInvalid || isParameterInvalid) {
            //配置中断请求，则过滤器返回，不再执行后续的拦截器链条上的内容
            if (isInterruptChain =="1") {
                logger.info("XssCheckFilter filter execute filter check return false,用户输入非法.");
                return;
            } else {
                logger.error("XssCheckFilter detect xss request: " + httpRequest.getServletPath());
            }
        }

        //校验通过，则继续执行下一个过滤器
        filterChain.doFilter(servletRequest, servletResponse);
    }

    @Override
    public void destroy() {
        logger.info("XssCheckFilter filter execute destroy.");
    }
}
